home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume4 / se / part6 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  21.0 KB

  1. From: Jeff Lee <talcott!seismo!gatech!jeff>
  2. Subject: Georgia Tech 'se' screen editor (Part 6 of 8)
  3. Keywords: Software Tools, Yet Another Screen Editor, Both BSD and USG
  4. Newsgroups: mod.sources
  5. Approved: jpn@panda.UUCP
  6.  
  7. Mod.sources:  Volume 4, Issue 87
  8. Submitted by: Jeff Lee <seismo!gatech!jeff>
  9.  
  10. #! /bin/sh
  11. # This is a shell archive, meaning:
  12. # 1. Remove everything above the #! /bin/sh line.
  13. # 2. Save the resulting text in a file.
  14. # 3. Execute the file with /bin/sh (not csh) to create:
  15. #    libchangetty
  16. #    pat
  17. # This archive created: Tue Apr 29 10:41:07 1986
  18. export PATH; PATH=/bin:/usr/bin:$PATH
  19. if test ! -d 'libchangetty'
  20. then
  21.     echo shar: "creating directory 'libchangetty'"
  22.     mkdir 'libchangetty'
  23. fi
  24. echo shar: "entering directory 'libchangetty'"
  25. cd 'libchangetty'
  26. echo shar: "extracting 'changetty.c'" '(5419 characters)'
  27. if test -f 'changetty.c'
  28. then
  29.     echo shar: "will not over-write existing file 'changetty.c'"
  30. else
  31. cat << \SHAR_EOF > 'changetty.c'
  32. /*
  33. ** changetty.c
  34. **
  35. ** Localize in one place all the data and functions
  36. ** needed to change to and from cbreak mode for
  37. ** the se screen editor.
  38. **
  39. ** Only functions available to rest of se are:
  40. ** ttyedit(), ttynormal(), and getspeed().
  41. **
  42. ** If USG is defined, we use the System V TTY driver.
  43. ** Otherwise (the default) we use the Berkeley terminal driver.
  44. **
  45. ** If we are using System V, then the Release 2 version does not
  46. ** need ospeed.  If not release 2, we assume Release 1 that someone
  47. ** have moved the BSD termlib to.
  48. */
  49.  
  50. #include "../ascii.h"
  51. #include "../constdefs.h"
  52.  
  53. #ifdef USG
  54. #include <termio.h>
  55. #else
  56. #include <sgtty.h>
  57. #endif
  58.  
  59. #if defined (BSD) || ! defined (S5R2)
  60. extern short ospeed;        /* from the termlib library */
  61. static int set_ospeed = NO;
  62. #endif
  63.  
  64. #ifdef USG
  65. /* all the info needed for the System V terminal driver */
  66.  
  67. typedef struct termio TTYINFO;    /* S5 control flags */
  68. #else
  69. /* all the info needed for the Berkeley terminal driver */
  70.  
  71. typedef struct junk {        /* terminal information */
  72.     struct sgttyb sgttyb;    /* V7 control flags */
  73.     struct tchars tchars;    /* V7 control characters */
  74.     short local;        /* local mode settings */
  75.     struct ltchars ltchars;    /* local control characters */
  76.     } TTYINFO;
  77. #endif
  78.  
  79. static TTYINFO OldTtyInfo;    /* initial state of terminal */
  80. static TTYINFO NewTtyInfo;    /* modified state for editing */
  81.  
  82. static int first = YES;        /* first time anything called */
  83.  
  84.  
  85. static init()
  86. {
  87.     if (gttyinfo(1, &OldTtyInfo) == -1)    /* get current state */
  88.         error ("couldn't get TTY info from system. get help!\n");
  89.  
  90.     NewTtyInfo = OldTtyInfo;    /* copy it */
  91.     mttyinfo(&NewTtyInfo);        /* change, but don't reset terminal */
  92.     /* really should check the return value here ... */
  93. }
  94.  
  95.  
  96. ttyedit()    /* set the terminal to correct modes for editing */
  97. {
  98.     if (first == YES)
  99.     {
  100.         first = NO;
  101.         init();
  102.     }
  103.  
  104.     sttyinfo(1, &NewTtyInfo);    /* make the change */
  105.     /* really should check the return value here too ... */
  106. }
  107.  
  108. ttynormal()    /* set the terminal to correct modes for normal use */
  109. {
  110.     if (first)
  111.     {
  112.         first = NO;
  113.         init();
  114.     }
  115.  
  116.     sttyinfo(1, &OldTtyInfo);    /* make the change */
  117. }
  118.  
  119. /* getspeed --- find out the terminal speed in characters/second */
  120. /*        this routine only used if terminal types are hardwired */
  121. /*        into se, however, since it will be in an archive, the */
  122. /*        loader won't grab it if it isn't needed. */
  123.  
  124. int getspeed(fd)
  125. int fd;
  126. {
  127.     register int i;
  128.     TTYINFO ttybuf;
  129.     static struct brstruct {
  130.         int unixrate;
  131.         int cps;
  132.         int baudrate;
  133.         } stab[] = {
  134.             B0,    0,    0,
  135.             B50,    5,    50,
  136.             B75,    8,    75,
  137.             B110,    10,    110,
  138.             B134,    14,    134,
  139.             B150,    15,    150,
  140.             B200,    20,    200,
  141.             B300,    30,    300,
  142.             B600,    60,    600,
  143.             B1200,    120,    1200,
  144.             B1800,    180,    1800,
  145.             B2400,    240,    2400,
  146.             B4800,    480,    4800,
  147.             B9600,    960,    9600
  148.         };
  149.  
  150.     if (first)        /* might as well set it here, too */
  151.     {
  152.         first = NO;
  153.         init();
  154.     }
  155.  
  156.     if (gttyinfo(fd, &ttybuf) == -1)
  157.         return 960;
  158.  
  159.     for (i = 0; i < sizeof(stab) / sizeof(struct brstruct); i++)
  160. #ifdef USG
  161.         if (stab[i].unixrate == (ttybuf.c_cflag & 017))
  162. #else
  163.         if (stab[i].unixrate == (ttybuf.sgttyb.sg_ospeed))
  164. #endif
  165.             return stab[i].cps;
  166.  
  167.     return 960;
  168. }
  169.  
  170. /* gttyinfo --- make all necessary calls to obtain terminal status */
  171.  
  172. static int gttyinfo(fd, buf)
  173. int fd;        /* file descriptor of terminal */
  174. TTYINFO *buf;    /* terminal info buffer to be filled in */
  175. {
  176. #ifdef USG
  177.     if (ioctl(fd, TCGETA, buf) < 0)
  178. #else
  179.     if (gtty(fd, &(buf->sgttyb))  < 0
  180.         || ioctl(fd, TIOCGETC, &(buf->tchars)) < 0
  181.         || ioctl(fd, TIOCLGET, &(buf->local)) < 0
  182.         || ioctl(fd, TIOCGLTC, &(buf->ltchars)) < 0)
  183. #endif
  184.     {
  185.         return -1;
  186.     }
  187.  
  188. #if defined (BSD) || ! defined (S5R2)
  189.     if (set_ospeed == NO)
  190.     {
  191.         set_ospeed = YES;
  192. #ifdef BSD
  193.         ospeed = (buf->sgttyb).sg_ospeed;
  194. #else
  195.         ospeed = buf->c_cflag & 017;    /* tty speed, see termio(7) */
  196. #endif
  197.     }
  198. #endif
  199.  
  200.     return 0;
  201. }
  202.  
  203. /* mttyinfo --- modify a TTYINFO structure for interactive operation */
  204.  
  205. static int mttyinfo(buf)
  206. TTYINFO *buf;        /* buffer containing TTYINFO to be modified */
  207. {
  208. #ifdef USG
  209.     buf->c_cc[0] = DLE;    /* interrupt */
  210.     buf->c_cc[1] = -1;    /* ignore quit */
  211.     buf->c_cc[4] = 1;    /* min # chars to read */
  212.     buf->c_cc[5] = 1;    /* min time to wait */
  213.  
  214.     buf->c_iflag &= ~(INLCR|IGNCR|ICRNL);    /* allow CR to come thru */
  215.     buf->c_lflag |= ISIG|NOFLSH;    /* keep these bits */
  216.     buf->c_lflag &= ~(ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
  217. #else
  218. #ifdef GITVAX
  219.     static struct tchars newtchars = {DLE, -1, -1, -1, EOT, -1};
  220.     /* allows control-s and -q to be control charactes that se sees */
  221. #else
  222.     static struct tchars newtchars = {DLE, -1, DC1, DC3, EOT, -1};
  223. #endif
  224.     static struct ltchars newltchars = {-1, -1, -1, -1, -1, -1};
  225.  
  226.     buf->sgttyb.sg_flags |= (CBREAK);    /* keep these bits */
  227.     buf->sgttyb.sg_flags &= ~(ECHO|CRMOD|LCASE|RAW|ALLDELAY);
  228.     buf->tchars = newtchars;
  229.     /* buf->local |= (LLITOUT);    /* Dan Forsyth says to comment out */
  230.     buf->local &= ~(LCRTBS|LCRTERA|LPRTERA|LTOSTOP|LFLUSHO|LCRTKIL|
  231. #ifndef BSD4_2
  232.                 LINTRUP|
  233. #endif
  234.                 LCTLECH|LPENDIN);
  235.     buf->ltchars = newltchars;
  236. #endif
  237.     return 0;
  238. }
  239.  
  240. /* sttyinfo --- make all necessary calls to set terminal status */
  241.  
  242. static int sttyinfo(fd, buf)
  243. int fd;        /* file descriptor of terminal */
  244. TTYINFO *buf;    /* terminal info buffer */
  245. {
  246. #ifdef USG
  247.     if (ioctl(fd, TCSETAW, buf) < 0)
  248. #else
  249.     if (ioctl(fd, TIOCSETN, &(buf->sgttyb)) < 0
  250.             || ioctl(fd, TIOCSETC, &(buf->tchars)) < 0
  251.             || ioctl(fd, TIOCLSET, &(buf->local)) < 0
  252.             || ioctl(fd, TIOCSLTC, &(buf->ltchars)) < 0)
  253. #endif
  254.         return    -1;
  255.  
  256.     return 0;
  257. }
  258. SHAR_EOF
  259. fi
  260. echo shar: "extracting 'makefile'" '(478 characters)'
  261. if test -f 'makefile'
  262. then
  263.     echo shar: "will not over-write existing file 'makefile'"
  264. else
  265. cat << \SHAR_EOF > 'makefile'
  266. # makefile for libchangetty.a -- terminal resetting functions
  267.  
  268. TARGET= libchangetty.a
  269. SRCS= changetty.c
  270. OBJS= changetty.o
  271. PRINTS= $(SRCS) makefile
  272.  
  273. CFLAGS= -O `cat ../flags`
  274.  
  275. $(TARGET): $(OBJS) ../flags
  276.     ar ruv $(TARGET) $(OBJS)
  277.     if test -r /usr/bin/ranlib; then /usr/bin/ranlib $(TARGET); fi
  278.  
  279. clean:
  280.     rm -fr $(OBJS)
  281.  
  282. clobber: clean
  283.     rm -fr $(TARGET) print2
  284.  
  285. print:
  286.     prt $(PRINTS) | lpr -b 'tty lib'
  287.     touch print2
  288.  
  289. print2: $(PRINTS)
  290.     prt $? | lpr -b 'new tty lib'
  291.     touch print2
  292. SHAR_EOF
  293. fi
  294. echo shar: "done with directory 'libchangetty'"
  295. cd ..
  296. if test ! -d 'pat'
  297. then
  298.     echo shar: "creating directory 'pat'"
  299.     mkdir 'pat'
  300. fi
  301. echo shar: "entering directory 'pat'"
  302. cd 'pat'
  303. echo shar: "extracting 'pat.c'" '(11979 characters)'
  304. if test -f 'pat.c'
  305. then
  306.     echo shar: "will not over-write existing file 'pat.c'"
  307. else
  308. cat << \SHAR_EOF > 'pat.c'
  309. /*
  310. ** pat.c
  311. **
  312. ** pattern matching subroutines for the se screen editor.
  313. ** knows about both Unix and SWT style patterns.
  314. **
  315. ** routines declared static are not necessary for the rest
  316. ** of the editor, therefore make them static in the name
  317. ** of modularity.
  318. */
  319.  
  320. #include <stdio.h>
  321. #include <ctype.h>
  322. #include "../constdefs.h"
  323.  
  324. /* Definitions used only for pattern matching */
  325.  
  326. #define AND             '&'
  327. #define CCL             '['
  328. #define CCLEND          ']'
  329. #define CHAR            'a'
  330. #define CLOSIZE         1
  331. #define CLOSURE         '*'
  332. #define DASH            '-'
  333. #define DITTO           0200
  334. #define EOL             '$'
  335. #define NCCL            'n'
  336. #define NEWLINE         '\n'
  337. #define TAB             '\t'
  338.  
  339. /* variables which are changeable if using unix style or swt style */
  340. /* initially unix style */
  341. static char ANY = '.';
  342. static char BOL = '^';
  343. static char NOTINCCL = '^';
  344. static char START_TAG = '(';
  345. static char STOP_TAG = ')';
  346. static char ESCAPE = '\\';
  347. static int unix_style = YES;
  348.  
  349. /* Array dimensions and other limit values */
  350. #define MAXLINE         128
  351. #define MAXPAT          128
  352.  
  353. /* Pattern matching subroutines: */
  354.  
  355. /* set_patterns -- tell the pattern routines what style patterns we're using */
  356.  
  357. set_patterns(tounix)
  358. int tounix;
  359. {
  360.     if (tounix == YES)
  361.     {
  362.         ANY = '.';
  363.         BOL = '^';
  364.         NOTINCCL = '^';
  365.         START_TAG = '(';
  366.         STOP_TAG = ')';
  367.         ESCAPE = '\\';
  368.         unix_style = YES;
  369.     }
  370.     else
  371.     {
  372.         ANY = '?';
  373.         BOL = '%';
  374.         NOTINCCL = '~';
  375.         START_TAG = '{';
  376.         STOP_TAG = '}';
  377.         ESCAPE = '@';
  378.         unix_style = NO;
  379.     }
  380. }
  381.  
  382. /* match () --- find match anywhere on line */
  383.  
  384. match (lin, pat)
  385. register char lin[];
  386. register char pat[];
  387. {
  388.     int junk[9];
  389.     register char *pc;
  390.  
  391.     for (pc = lin; *pc != EOS; pc++)
  392.         if (amatch (lin, pc - lin, pat, junk, junk) >= 0)
  393.             return (YES);
  394.     return (NO);
  395. }
  396.  
  397.  
  398. /* amatch() --- (recursive) look for match starting at lin[from] */
  399.  
  400. amatch(lin, from, pat, tagbeg, tagend)
  401. int from, tagbeg[], tagend[];
  402. char lin[], pat[];
  403. {
  404.     char *ch, *lastc;
  405.     register char *ppat;
  406.     int k;
  407.  
  408.     lastc = lin + from;     /* next unexamined input character */
  409.     for (ppat = pat; *ppat != EOS; ppat += patsiz (ppat))
  410.         if (*ppat == CLOSURE)   /* a closure entry */
  411.         {
  412.             ppat++;
  413.             for (ch = lastc; *ch != EOS; )
  414.                 /* match as many as possible */
  415.                 if (omatch (lin, &ch, ppat) == NO)
  416.                     break;
  417.             /*
  418.              * ch now points to character that made us fail
  419.              * try to match rest of pattern against rest of input
  420.              * shrink the closure by 1 after each failure
  421.              */
  422.             for (ppat += patsiz (ppat); ch >= lastc; ch--)
  423.                 /* successful match of rest of pattern */
  424.                 if ((k = amatch (lin, ch - lin, ppat, tagbeg,
  425.                     tagend)) >= 0)
  426.                     break;
  427.             lastc = lin + k;        /* if k < 0, failure;
  428.                          * if k >= 0, success */
  429.             break;
  430.         }
  431.         else if (*ppat == START_TAG)
  432.             tagbeg[*(ppat + 1)] = lastc - lin;
  433.         else if (*ppat == STOP_TAG)
  434.             tagend[*(ppat + 1)] = lastc - lin;
  435.             /* non-closure */
  436.         else if (omatch (lin, &lastc, ppat) == NO)
  437.             return (-1);
  438.         /* else
  439.             omatch succeeded */
  440.     return (lastc - lin);
  441. }
  442.  
  443.  
  444. /* omatch () --- try to match a single pattern at ppat */
  445.  
  446. static omatch (lin, adplin, ppat)
  447. char lin[], **adplin, *ppat;
  448. {
  449.     register char *plin;
  450.     register int bump, retval;
  451.  
  452.     plin = *adplin;
  453.     retval = NO;
  454.     if (*plin == EOS)
  455.         return (retval);
  456.     bump = -1;
  457.     if (*ppat == CHAR)
  458.     {
  459.         if (*plin == *(ppat + 1))
  460.             bump = 1;
  461.     }
  462.  
  463.     else if (*ppat == BOL)
  464.     {
  465.         if (plin == lin)
  466.             bump = 0;
  467.     }
  468.  
  469.     else if (*ppat == ANY)
  470.     {
  471.         if (*plin != NEWLINE)
  472.             bump = 1;
  473.     }
  474.  
  475.     else if (*ppat == EOL)
  476.     {
  477.         if (*plin == NEWLINE)
  478.             bump = 0;
  479.     }
  480.  
  481.     else if(*ppat == CCL)
  482.     {
  483.         if (locate (*plin, ppat + 1) == YES)
  484.             bump = 1;
  485.     }
  486.  
  487.     else if(*ppat == NCCL)
  488.     {
  489.         if (*plin != NEWLINE && locate (*plin, ppat + 1) == NO)
  490.             bump = 1;
  491.     }
  492.     else
  493.         error ("in omatch: can't happen.");
  494.  
  495.     if (bump >= 0)
  496.     {
  497.         *adplin += bump;
  498.         retval = YES;
  499.     }
  500.     return (retval);
  501. }
  502.  
  503.  
  504. /* locate () --- look for c in char class at ppat */
  505.  
  506. static locate (c, ppat)
  507. register char c, *ppat;
  508. {
  509.     register char *pclas;
  510.  
  511.     /* size of class is at ppat, characters follow */
  512.     for (pclas = ppat + *ppat; pclas > ppat; pclas--)
  513.         if (c == *pclas)
  514.             return (YES);
  515.     return (NO);
  516. }
  517.  
  518.  
  519. /* patsiz () --- returns size of pattern entry at ppat */
  520.  
  521. static patsiz (ppat)
  522. register char *ppat;
  523. {
  524.  
  525.     if (*ppat == CHAR || *ppat == START_TAG || *ppat == STOP_TAG)
  526.         return (2);
  527.  
  528.     else if (*ppat == BOL || *ppat == EOL || *ppat == ANY)
  529.         return (1);
  530.  
  531.     else if (*ppat == CCL || *ppat == NCCL)
  532.         return (*(ppat + 1) + 2);
  533.  
  534.     else if (*ppat == CLOSURE)
  535.         return (CLOSIZE);
  536.  
  537.     else
  538.         error ("in patsiz: can't happen.");
  539. }
  540.  
  541.  
  542. /* makpat () --- make pattern from arg[from], terminate at delim */
  543.  
  544. makpat (arg, from, delim, pat)
  545. char arg[], delim, pat[];
  546. int from;
  547. {
  548.     char ch, esc ();
  549.     int argsub, junk, lastsub, ls, patsub, tag_nest, tag_num, tag_stack[9];
  550.  
  551.     lastsub = patsub = 0;
  552.     tag_num = -1;
  553.     tag_nest = -1;
  554.     for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
  555.         argsub++)
  556.     {
  557.         ls = patsub;
  558.         if (arg[argsub] == ANY)
  559.             junk = addset (ANY, pat, &patsub, MAXPAT);
  560.         else if (arg[argsub] == BOL && argsub == from)
  561.             junk = addset (BOL, pat, &patsub, MAXPAT);
  562.         else if (arg[argsub] == EOL && arg[argsub + 1] == delim)
  563.             junk = addset (EOL, pat, &patsub, MAXPAT);
  564.         else if (arg[argsub] == CCL)
  565.         {
  566.             if (getccl (arg, &argsub, pat, &patsub) == ERR)
  567.                 return (ERR);
  568.         }
  569.         else if (arg[argsub] == CLOSURE && argsub > from)
  570.         {
  571.             ls = lastsub;
  572.             if (pat[ls] == BOL || pat[ls] == EOL ||
  573.                 pat[ls] == CLOSURE || pat[ls] == START_TAG ||
  574.                 pat[ls] == STOP_TAG)
  575.                 break;
  576.             stclos (pat, &patsub, &lastsub);
  577.         }
  578.         else if (start_tag(arg, &argsub))
  579.                 /* start_tag knows about unix or not */
  580.         {
  581.             /* too many tagged sub-patterns */
  582.             if (tag_num >= 8)
  583.                 break;
  584.             tag_num++;
  585.             tag_nest++;
  586.             tag_stack[tag_nest] = tag_num;
  587.             junk = addset (START_TAG, pat, &patsub, MAXPAT);
  588.             junk = addset (tag_num, pat, &patsub, MAXPAT);
  589.         }
  590.         else if (stop_tag(arg, &argsub) && tag_nest > -1)
  591.                 /* stop_tag knows about unix or not */
  592.         {
  593.             junk = addset (STOP_TAG, pat, &patsub, MAXPAT);
  594.             junk = addset (tag_stack[tag_nest], pat, &patsub, MAXPAT);
  595.             tag_nest--;
  596.         }
  597.         else
  598.         {
  599.             junk = addset (CHAR, pat, &patsub, MAXPAT);
  600.  
  601.             /* don't allow match of newline other than via $ */
  602.             if ((ch = esc(arg, &argsub)) == NEWLINE)
  603.                 return (ERR);
  604.             junk = addset (ch, pat, &patsub, MAXPAT);
  605.         }
  606.         lastsub = ls;
  607.     }
  608.  
  609.     if (arg[argsub] != delim)               /* terminated early */
  610.         return (ERR);
  611.     else if (addset (EOS, pat, &patsub, MAXPAT) == NO)      /* no room */
  612.         return (ERR);
  613.     else if (tag_nest != -1)
  614.         return (ERR);
  615.     else
  616.         return (argsub);
  617. }
  618.  
  619.  
  620. /* getccl () --- expand char class at arg[*pasub] into pat[*pindex] */
  621.  
  622. static getccl (arg, pasub, pat, pindex)
  623. char arg[], pat[];
  624. int *pasub, *pindex;
  625. {
  626.     int junk, start;
  627.  
  628.     (*pasub)++;             /* skip over [ */
  629.     if (arg[*pasub] == NOTINCCL)
  630.     {
  631.         junk = addset (NCCL, pat, pindex, MAXPAT);
  632.         (*pasub)++;
  633.     }
  634.     else
  635.         junk = addset (CCL, pat, pindex, MAXPAT);
  636.  
  637.     start = *pindex;
  638.     junk = addset (0, pat, pindex, MAXPAT); /* leave room for count */
  639.     filset (CCLEND, arg, pasub, pat, pindex, MAXPAT);
  640.     pat[start] = *pindex - start - 1;
  641.  
  642.     if (arg[*pasub] == CCLEND)
  643.         return (OK);
  644.     else
  645.         return (ERR);
  646. }
  647.  
  648.  
  649. /* stclos () --- insert closure entry at pat[*ppatsub] */
  650.  
  651. static stclos (pat, ppatsub, plastsub)
  652. char pat[];
  653. int *ppatsub, *plastsub;
  654. {
  655.     int i, j, junk;
  656.  
  657.     for (i = *ppatsub - 1; i >= *plastsub; i--)     /* make a hole */
  658.     {
  659.         j = i + CLOSIZE;
  660.         junk = addset (pat[i], pat, &j, MAXPAT);
  661.     }
  662.     *ppatsub += CLOSIZE;
  663.     /* put closure in it */
  664.     junk = addset (CLOSURE, pat, plastsub, MAXPAT);
  665. }
  666.  
  667.  
  668. /* maksub () --- make substitution string in sub */
  669.  
  670. maksub (arg, from, delim, sub)
  671. char arg[], delim, sub[];
  672. int from;
  673. {
  674.     char esc ();
  675.     int argsub, index, junk;
  676.  
  677.     index = 0;
  678.     for (argsub = from; arg[argsub] != delim && arg[argsub] != EOS;
  679.         argsub++)
  680.         if (arg[argsub] == AND)
  681.         {
  682.             junk = addset (DITTO, sub, &index, MAXPAT);
  683.             junk = addset (0, sub, &index, MAXPAT);
  684.         }
  685.         else if (arg[argsub] == ESCAPE && isdigit (arg[argsub + 1]))
  686.         {
  687.             argsub++;
  688.             junk = addset (DITTO, sub, &index, MAXPAT);
  689.             junk = addset (arg[argsub] - '0', sub, &index, MAXPAT);
  690.         }
  691.         else
  692.             junk = addset (esc (arg, &argsub), sub, &index, MAXPAT);
  693.     if (arg[argsub] != delim)               /* missing delimeter */
  694.         return (ERR);
  695.     else if (addset (EOS, sub, &index, MAXPAT) == NO)       /* no room */
  696.         return (ERR);
  697.     else
  698.         return (argsub);
  699. }
  700.  
  701.  
  702. /* catsub () --- add replacement text to end of new */
  703.  
  704. catsub (lin, from, to, sub, new, k, maxnew)
  705. register char lin[], new[], sub[];
  706. int from[], *k, maxnew, to[];
  707. {
  708.     int junk, ri;
  709.     register int i, j;
  710.  
  711.     for (i = 0; sub[i] != EOS; i++)
  712.         if ((sub[i] & 0xff) == DITTO)
  713.         {
  714.             ri = sub[++i];
  715.             for (j = from[ri]; j < to[ri]; j++)
  716.                 junk = addset (lin[j], new, k, maxnew);
  717.         }
  718.         else
  719.             junk = addset (sub[i], new, k, maxnew);
  720. }
  721.  
  722.  
  723. /* filset () --- expand set at array[*pasub] into set[*pindex], stop at delim */
  724.  
  725. filset (delim, array, pasub, set, pindex, maxset)
  726. char array[], delim, set[];
  727. int maxset, *pasub, *pindex;
  728. {
  729.     char esc ();
  730.     int junk;
  731.     static char digits[] = "0123456789";
  732.     static char lowalf[] = "abcdefghijklmnopqrstuvwxyz";
  733.     static char upalf[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  734.  
  735.     for ( ; array[*pasub] != delim && array[*pasub] != EOS; (*pasub)++)
  736.         if (array[*pasub] == ESCAPE)
  737.             junk = addset (esc (array, pasub), set, pindex, maxset);
  738.         else if (array[*pasub] != DASH)
  739.             junk = addset (array[*pasub], set, pindex, maxset);
  740.             /* literal DASH */
  741.         else if (*pindex <= 0 || array[*pasub + 1] == EOS ||
  742.             array[*pasub + 1] == delim)
  743.             junk = addset (DASH, set, pindex, maxset);
  744.         /* else if (index (digits, set[*pindex - 1]) >= 0) */
  745.         else if (isdigit(set[*pindex - 1]))
  746.             dodash (digits, array, pasub, set, pindex, maxset);
  747.         /* else if(index (lowalf, set[*pindex - 1]) >= 0) */
  748.         else if (islower(set[*pindex - 1]))
  749.             dodash (lowalf, array, pasub, set, pindex, maxset);
  750.         /* else if (index (upalf, set[*pindex - 1]) >= 0) */
  751.         else if (isupper(set[*pindex - 1]))
  752.             dodash (upalf, array, pasub, set, pindex, maxset);
  753.         else
  754.             junk = addset (DASH, set, pindex, maxset);
  755. }
  756.  
  757.  
  758. /*
  759. ** dodash () --- expand array[*pasub - 1]-array[*pasub + 1] into set[*pindex],
  760. **               from valid
  761. */
  762.  
  763. static dodash (valid, array, pasub, set, pindex, maxset)
  764. char array[], set[], valid[];
  765. int maxset, *pasub, *pindex;
  766. {
  767.     char esc ();
  768.     int junk, k, limit;
  769.  
  770.     (*pasub)++;
  771.     (*pindex)--;
  772.     limit = index (valid, esc (array, pasub));
  773.     for (k = index (valid, set[*pindex]); k <= limit; k++)
  774.         junk = addset (valid[k], set, pindex, maxset);
  775. }
  776.  
  777.  
  778. /* addset () --- put c in set[*pindex];  if it fits, increment *pindex */
  779.  
  780. addset (c, set, pindex, maxsiz)
  781. int maxsiz, *pindex;
  782. char c, set[];
  783. {
  784.  
  785.     if (*pindex >= maxsiz)
  786.         return (NO);
  787.     else
  788.     {
  789.         set[(*pindex)++] = c;
  790.         return (YES);
  791.     }
  792. }
  793.  
  794.  
  795. /* esc () --- map array[*pindex] into escaped character if appropriate */
  796.  
  797. char esc (array, pindex)
  798. char array[];
  799. int *pindex;
  800. {
  801.  
  802.     if (array[*pindex] != ESCAPE)
  803.         return (array[*pindex]);
  804.     else if (array[*pindex + 1] == EOS)     /* ESCAPE not special at end */
  805.         return (ESCAPE);
  806.     else
  807.     {
  808.         if (array[++(*pindex)] == 'n')
  809.             return (NEWLINE);
  810.         else if (array[*pindex] == 't')
  811.             return (TAB);
  812.         else
  813.             return (array[*pindex]);
  814.     }
  815. }
  816.  
  817. /* start_tag --- determine if we've seen the start of a tagged pattern */
  818.  
  819. static int start_tag(arg, argsub)
  820. char *arg;
  821. int *argsub;
  822. {
  823.     if (unix_style)
  824.         if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == START_TAG)
  825.         {
  826.             (*argsub)++;
  827.             return (YES);
  828.         }
  829.         else
  830.             return (NO);
  831.     else
  832.         if (arg[*argsub] == START_TAG)
  833.             return (YES);
  834.         else
  835.             return (NO);
  836. }
  837.  
  838. /* stop_tag --- determine if we've seen the end of a tagged pattern */
  839.  
  840. static int stop_tag(arg, argsub)
  841. char *arg;
  842. int *argsub;
  843. {
  844.     if (unix_style)
  845.         if (arg[*argsub] == ESCAPE && arg[*argsub + 1] == STOP_TAG)
  846.         {
  847.             (*argsub)++;
  848.             return (YES);
  849.         }
  850.         else
  851.             return (NO);
  852.     else
  853.         if (arg[*argsub] == STOP_TAG)
  854.             return (YES);
  855.         else
  856.             return (NO);
  857. }
  858. SHAR_EOF
  859. fi
  860. echo shar: "extracting 'makefile'" '(410 characters)'
  861. if test -f 'makefile'
  862. then
  863.     echo shar: "will not over-write existing file 'makefile'"
  864. else
  865. cat << \SHAR_EOF > 'makefile'
  866. # makefile for pattern library for 'se'
  867.  
  868. CFLAGS=-O
  869.  
  870. PR=pr
  871.  
  872. libpat.a: pat.o
  873.     ar ruv libpat.a pat.o
  874.     if test -r /usr/bin/ranlib; then /usr/bin/ranlib libpat.a; fi
  875.  
  876. pat.o: pat.c
  877.  
  878. install: libpat.a
  879.     cp libpat.a /usr/lib
  880.  
  881. print:
  882.     $(PR) pat.c makefile | lpr -b 'pat lib'
  883.     touch print2
  884.  
  885. print2: pat.c makefile
  886.     $(PR) $? | lpr -b 'new pat lib'
  887.     touch print2
  888.  
  889. clean:
  890.     rm -f pat.o
  891.  
  892. clobber: clean
  893.     rm -f libpat.a print2
  894. SHAR_EOF
  895. fi
  896. echo shar: "extracting 'llib-lpat'" '(1270 characters)'
  897. if test -f 'llib-lpat'
  898. then
  899.     echo shar: "will not over-write existing file 'llib-lpat'"
  900. else
  901. cat << \SHAR_EOF > 'llib-lpat'
  902. /* llib-lpat --- lint library for pattern routines */
  903.  
  904. /*LINTLIBRARY*/
  905.  
  906. match (lin, pat)
  907. char lin[];
  908. char pat[];
  909. {
  910.     return 0;
  911. }          
  912.  
  913.  
  914. amatch(lin, from, pat, tagbeg, tagend)
  915. int from, tagbeg[], tagend[];
  916. char lin[], pat[];
  917. {
  918.     return 0;
  919. }
  920.  
  921.  
  922. static omatch (lin, adplin, ppat)
  923. char lin[], **adplin, *ppat;
  924. {
  925.     return 0;
  926. }
  927.  
  928.  
  929. static locate (c, ppat)
  930. char c, *ppat;
  931. {
  932.     return 0;
  933. }
  934.  
  935.  
  936. static patsiz (ppat)
  937. char *ppat;
  938. {
  939.     return 0;
  940. }
  941.  
  942.  
  943. makpat (arg, from, delim, pat)
  944. char arg[], delim, pat[];
  945. int from;
  946. {
  947.     return 0;
  948. }
  949.  
  950.  
  951. static getccl (arg, pasub, pat, pindex)
  952. char arg[], pat[];
  953. int *pasub, *pindex;
  954. {
  955.     return 0;
  956. }
  957.  
  958.  
  959. static stclos (pat, ppatsub, plastsub)
  960. char pat[];
  961. int *ppatsub, *plastsub;
  962. {
  963. }
  964.  
  965.  
  966. maksub (arg, from, delim, sub)
  967. char arg[], delim, sub[];
  968. int from;
  969. {
  970.     return 0;
  971. }
  972.  
  973.  
  974. catsub (lin, from, to, sub, new, k, maxnew)
  975. char lin[], new[], sub[];
  976. int from[], *k, maxnew, to[];
  977. {
  978. }
  979.  
  980.  
  981. filset (delim, array, pasub, set, pindex, maxset)
  982. char array[], delim, set[];
  983. int maxset, *pasub, *pindex;
  984. {
  985. }
  986.  
  987.  
  988. static dodash (valid, array, pasub, set, pindex, maxset)
  989. char array[], set[], valid[];
  990. int maxset, *pasub, *pindex;
  991. {
  992. }
  993.  
  994.  
  995. addset (c, set, pindex, maxsiz)
  996. int maxsiz, *pindex;
  997. char c, set[];
  998. {
  999.     return 0;
  1000. }
  1001.  
  1002. char esc (array, pindex)
  1003. char array[];
  1004. int *pindex;
  1005. {
  1006.     return 0;
  1007. }
  1008. SHAR_EOF
  1009. fi
  1010. echo shar: "done with directory 'pat'"
  1011. cd ..
  1012. exit 0
  1013. #    End of shell archive
  1014.  
  1015.